import wx
import dataclasses
import toml
from typing import List
from dataclasses import dataclass, field

from gui.widgets.orderby_panel import OrderByPanel
from gui.widgets.symbols_search import SymbolListPanel, EVT_SYMBOLS_CHANGED


@dataclass
class Task:
    name: str = '策略'
    symbols: List[str] = field(default_factory=list)
    start_date: str = '20230101'
    end_date: str = '20231231'
    benchmark: str = '510300.SH'
from core.task import Task

class TaskConfigDialog(wx.Dialog):
    def __init__(self, parent, task=None):
        super().__init__(parent, title="任务配置", size=(1000, 700))
        self.task = task or Task()
        self.prevent_update = False
        self.controls = {}

        # 初始化顺序严格分为三步
        self.init_ui()  # 1. 先初始化界面
        self.bind_events()  # 2. 再绑定事件
        self.load_data()  # 3. 最后加载数据

        # 强制刷新布局
        self.Layout()
        self.Refresh()

    def init_ui(self):
        """完整UI初始化方法"""
        # 主布局
        main_sizer = wx.BoxSizer(wx.VERTICAL)

        # 分割窗口
        splitter = wx.SplitterWindow(self)
        main_sizer.Add(splitter, 1, wx.EXPAND)

        # 左面板（占60%宽度）
        left_panel = wx.Panel(splitter)
        self.init_left_panel(left_panel)

        # 右面板（占40%宽度）
        right_panel = wx.Panel(splitter)
        self.init_right_panel(right_panel)

        splitter.SplitVertically(left_panel, right_panel, sashPosition=600)
        splitter.SetMinimumPaneSize(400)  # 防止面板过小

        # 底部按钮
        btn_sizer = wx.BoxSizer(wx.HORIZONTAL)
        cancel_btn = wx.Button(self, wx.ID_CANCEL, "取消")
        save_btn = wx.Button(self, wx.ID_OK, "保存")
        btn_sizer.Add(cancel_btn, 0, wx.RIGHT, 10)
        btn_sizer.Add(save_btn, 0)
        main_sizer.Add(btn_sizer, 0, wx.ALIGN_CENTER | wx.ALL, 10)

        self.SetSizer(main_sizer)
        self.Centre()

    def init_left_panel(self, parent):
        """左面板布局（带强制尺寸设置）"""
        parent.SetMinSize((600, -1))  # 确保最小宽度

        main_sizer = wx.BoxSizer(wx.VERTICAL)

        # 基本设置分组
        group = wx.StaticBox(parent, label="基本设置")
        group_sizer = wx.StaticBoxSizer(group, wx.VERTICAL)

        # 策略名称
        self.controls["name"] = wx.TextCtrl(parent)
        self.create_label_row(group_sizer, parent, "策略名称：", self.controls["name"])

        # 标的列表（核心修复部分）
        static_text = wx.StaticText(parent, label="标的列表：")
        self.controls["symbols"] = SymbolListPanel(parent)
        self.controls["symbols"].SetMinSize((-1, 120))  # 固定高度

        # 使用GridBagSizer精确控制布局
        grid_sizer = wx.GridBagSizer(5, 5)
        grid_sizer.Add(static_text, pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL)
        grid_sizer.Add(self.controls["symbols"], pos=(1, 0), span=(1, 2), flag=wx.EXPAND)
        grid_sizer.AddGrowableCol(1)

        group_sizer.Add(grid_sizer, 1, wx.EXPAND | wx.ALL, 5)
        main_sizer.Add(group_sizer, 1, wx.EXPAND | wx.ALL, 5)

        self.controls["order_by"] = OrderByPanel(parent, self.task)
        main_sizer.Add(self.controls["order_by"], 0, wx.EXPAND | wx.TOP, 10)

        parent.SetSizer(main_sizer)
        parent.Layout()  # 立即刷新布局

    def init_right_panel(self, parent):
        """右面板布局"""
        parent.SetMinSize((400, -1))  # 确保最小宽度

        self.toml_ctrl = wx.TextCtrl(
            parent,
            style=wx.TE_MULTILINE | wx.TE_RICH2 | wx.TE_DONTWRAP
        )
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.toml_ctrl, 1, wx.EXPAND | wx.ALL, 5)
        parent.SetSizer(sizer)

    def create_label_row(self, sizer, parent, label, ctrl):
        """创建标签+控件的行布局"""
        h_sizer = wx.BoxSizer(wx.HORIZONTAL)
        static_text = wx.StaticText(parent, label=label)
        h_sizer.Add(static_text, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 5)
        h_sizer.Add(ctrl, 1, wx.EXPAND)
        sizer.Add(h_sizer, 0, wx.EXPAND | wx.BOTTOM, 10)

    def bind_events(self):
        """事件绑定"""
        self.Bind(EVT_SYMBOLS_CHANGED, self.on_symbols_changed)
        self.toml_ctrl.Bind(wx.EVT_TEXT, self.on_toml_changed)

    def load_data(self):
        """数据加载方法（带延迟加载保证UI就绪）"""
        wx.CallLater(100, self._delayed_load)  # 延迟100ms确保UI渲染完成

    def _delayed_load(self):
        """延迟加载数据"""
        try:
            self.prevent_update = True
            # 加载策略名称
            self.controls["name"].SetValue(self.task.name)

            # 核心修复：标的列表加载
            symbols_panel = self.controls["symbols"]
            symbols_panel.set_selected(self.task.symbols)
            symbols_panel.update_list()  # 强制刷新

            # 立即刷新布局
            symbols_panel.Layout()
            symbols_panel.Refresh()
        finally:
            self.prevent_update = False

    def on_symbols_changed(self, event):
        """标的列表变化处理"""
        if not self.prevent_update:
            self.update_from_controls()
            self.update_toml()

    def on_toml_changed(self, event):
        """TOML变化处理"""
        if not self.prevent_update:
            try:
                self.prevent_update = True
                self.task = Task(**toml.loads(self.toml_ctrl.GetValue()))
                self.update_controls()
            except Exception as e:
                wx.LogError(f"TOML解析错误: {str(e)}")
            finally:
                self.prevent_update = False

    def update_controls(self):
        """从Task更新控件"""
        try:
            self.prevent_update = True
            self.controls["name"].SetValue(self.task.name)
            self.controls["symbols"].set_selected(self.task.symbols)

            self.controls["order_by"].update_controls()
        finally:
            self.prevent_update = False

    def update_toml(self):
        """更新TOML显示"""
        if not self.prevent_update:
            try:
                self.prevent_update = True
                task_dict = dataclasses.asdict(self.task)
                self.toml_ctrl.SetValue(toml.dumps(task_dict))
            finally:
                self.prevent_update = False

    def update_from_controls(self):
        """从控件更新Task"""
        self.task.name = self.controls["name"].GetValue()
        self.task.symbols = self.controls["symbols"].get_selected()

        # 更新排序字段（新增部分）
        order_panel = self.controls["order_by"]
        self.task.order_by_signal = order_panel.signal_ctrl.GetValue()
        self.task.order_by_topK = order_panel.topK_ctrl.GetValue()
        self.task.order_by_dropN = order_panel.dropN_ctrl.GetValue()
        self.task.order_by_DESC = order_panel.desc_check.GetValue()

        # 触发TOML更新
        self.update_toml()

    def GetTask(self):
        """获取最终配置"""
        return self.task


if __name__ == "__main__":
    app = wx.App()
    task = Task()
    task.symbols = ["510300.SH", "510500.SH"]
    dlg = TaskConfigDialog(None, task)
    if dlg.ShowModal() == wx.ID_OK:
        print("保存配置:", dlg.GetTask())
    dlg.Destroy()
    app.MainLoop()